package com.cookor.poi.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cookor.poi.common.utils.DateUtils;
import com.cookor.poi.modules.weixin.account.Account;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

public class HttpUtils {
	public static void main(String[] args) {
		Map<String, Object> params = new ConcurrentHashMap<>();
//		Account account = Account.factory(uniacid);
		params.put("touser", "");
		String data = "{\"touser\":\"2oBm6BwSeNEsGrZHKQLJKqGLS-ng0\",\"template_id\":\"XuziRWQCwZCW-PCGOdx83TslF6UO2m8VUpE9aJ_xGpA\",\"url\":\"http://weixin.qq.com/download\",\"topcolor\":\"#000000\",\"data\":{\"first\": {\"value\":\"尊敬的光大闽通卡客户：\",\"color\":\"#000000\"},\"headinfo\":{\"value\":\"光大银行需扣回为您车牌号111车辆所垫付的福建省高速公路通行费用10元\",\"color\":\"#000000\"},\"Date\":{\"value\":\"2015年01月10日 10:10\",\"color\":\"#000000\"},\"Type\":{\"value\":\"扣回垫款\",\"color\":\"#000000\"},\"Money\":{\"value\":\"1\",\"color\":\"#000000\"},\"remark\":{\"value\":\"交易状态：扣款成功\\n备注：扣款成功，扣款银行卡账户尾号为111\",\"color\":\"#000000\"}}}";
		String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=Xplq2Tmc-6x3wpnOuVgXfxbXFY3S0f4GT9eTsZBT1EkjJEloeKUS1Z8odzwRLhgWIU7W9EfyyGap30rUqPkqkdg1iNmuj-CQpQZNoKz7HeI";
		httpRequest(url, "POST", data);
	}

	private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);

	/**
	 * 发起https请求并获取结果
	 *
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static String httpRequest(String requestUrl, String requestMethod,
                                     String outputStr) {
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			// httpUrlConn.set
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();

		} catch (ConnectException ce) {
			ce.printStackTrace();
			logger.error("Weixin server connection timed out.");
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return buffer.toString();
	}
	public static String post(String url, Map<String, String> params, String paramStr){
		URL u = null;
		HttpURLConnection con = null;
		StringBuffer sb = new StringBuffer();
		if(params!=null){
			for (Entry<String, String> e : params.entrySet()) {
				sb.append(e.getKey());
				sb.append("=");
				sb.append(e.getValue());
				sb.append("&");
			}
			sb.substring(0, sb.length() - 1);
		} else {
			sb.append(paramStr);
		}
		try {
			u = new URL(url);
			con = (HttpURLConnection) u.openConnection();
			con.setRequestMethod("POST");
			con.setDoOutput(true);
			con.setDoInput(true);
			con.setUseCaches(false);
			con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
			osw.write(sb.toString());
			osw.flush();
			osw.close();
			StringBuffer buffer = new StringBuffer();
			try {
				BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "GB2312"));
				String temp;
				while ((temp = br.readLine()) != null) {
					buffer.append(temp);
					buffer.append("\n");
				}
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
			return buffer.toString();
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			return "";
		} finally {
			if (con != null) {
				con.disconnect();
			}
		}
	}
	public static JSONObject httpRequest(String urladdr, String content)
			throws IOException {
		URL url = new URL(urladdr);
		HttpURLConnection httpConnection = (HttpURLConnection) url
				.openConnection();
		httpConnection.setDoOutput(true);
		httpConnection.setDoInput(true);
		httpConnection.setRequestMethod("POST");
		httpConnection.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded; charset=utf-8");
		httpConnection.setConnectTimeout(30000);
		httpConnection.setReadTimeout(30000);
		OutputStream os = httpConnection.getOutputStream();
		DataOutputStream dos = new DataOutputStream(os);
		dos.write(content.toString().getBytes("utf-8"));
		dos.flush();
		dos.close();
		int nResponseCode = httpConnection.getResponseCode();
		if (nResponseCode == 200) {
			DataInputStream dis = new DataInputStream(
					httpConnection.getInputStream());
			BufferedInputStream bis = new BufferedInputStream(dis);
			byte bRecByte[] = new byte[1025];
			int nByte = -1;
			ByteArrayOutputStream baoStream = new ByteArrayOutputStream();
			nByte = bis.read(bRecByte, 0, 1024);
			while (nByte != -1) {
				baoStream.write(bRecByte, 0, nByte);
				nByte = bis.read(bRecByte, 0, 1024);
			}
			byte abyte[] = baoStream.toByteArray();
			String strTempRecXml = new String(abyte, "utf-8");
			strTempRecXml = strTempRecXml.replaceAll("&lt;", "<");
			strTempRecXml = strTempRecXml.replaceAll("&gt;", ">");
			JSONObject jsonObject = JSONObject.parseObject(strTempRecXml);
			return jsonObject;
		}
		httpConnection.disconnect();
		return null;
	}

	public static boolean isAjax(HttpServletRequest request) {
		return (request.getHeader("X-Requested-With") != null && "XMLHttpRequest"
				.equals(request.getHeader("X-Requested-With").toString()));
	}

	public static String getVisitUrl(HttpServletRequest request){
		StringBuffer toUrl = request.getRequestURL();
		String prms = request.getQueryString();
		if (prms!=null){
			toUrl.append("?");
			toUrl.append(prms);
		}
		return toUrl.toString();
	}
	public static String getSiteRoot(HttpServletRequest request){
		StringBuffer url = request.getRequestURL();
		String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
		return tempContextUrl.toString();
	}

	public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) {
		String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP"};
		if (otherHeaderNames != null && otherHeaderNames.length != 0) {
//			headers = (String[])CollectionUtils.addAll(new String[][]{headers, otherHeaderNames}
		}

		String[] arr$ = headers;
		int len$ = headers.length;

		String ip;
		for(int i$ = 0; i$ < len$; ++i$) {
			String header = arr$[i$];
			ip = request.getHeader(header);
			if (!isUnknow(ip)) {
				return getMultistageReverseProxyIp(ip);
			}
		}

		ip = request.getRemoteAddr();
		return getMultistageReverseProxyIp(ip);
	}

	public static boolean isUnknow(String checkString) {
		return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
	}

	public static String getMultistageReverseProxyIp(String ip) {
		if (ip != null && ip.indexOf(",") > 0) {
			String[] ips = ip.trim().split(",");
			String[] arr$ = ips;
			int len$ = ips.length;

			for(int i$ = 0; i$ < len$; ++i$) {
				String subIp = arr$[i$];
				if (!isUnknow(subIp)) {
					ip = subIp;
					break;
				}
			}
		}

		return ip;
	}

	public static String sendPostRequest(String url, String jsonInputString, String token) throws IOException {
		URL apiUrl = new URL(url);
		HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();

		// Set up the connection
		connection.setRequestMethod("POST");
		connection.setRequestProperty("Content-Type", "application/json");
		if(token != null){
			connection.setRequestProperty("token", token);
		}
		connection.setDoOutput(true);

		// Send the JSON payload
		if(jsonInputString != null){
			try (OutputStream os = connection.getOutputStream()) {
				byte[] input = jsonInputString.getBytes("utf-8");
				os.write(input, 0, input.length);
			}
		}

		// Read the response
		try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {
			StringBuilder response = new StringBuilder();
			String responseLine;
			while ((responseLine = br.readLine()) != null) {
				response.append(responseLine.trim());
			}
			return response.toString();
		} finally {
			connection.disconnect();
		}
	}


}
